package fhjoanneum.itm11.antesk.simplehack;
import java.util.*;

public class Map
{
	// Members -----------------------------------------------------------
	private int height;
	private int width;
	private Vector<Tile> tiles = new Vector<Tile>();
	private Config config = new Config();
	private PlayerCharacter player_character;
		
	// Constructor -------------------------------------------------------
	public Map()
	{
		this.height = 10;
		this.width = 10;
	}
		
	// Methods ===========================================================
	
	// Getters and setters -----------------------------------------------
	public int getWidth()
	{
		return this.width;
	}
	public int getHeight()
	{
		return this.height;
	}
	public PlayerCharacter getPlayerCharacter()
	{
		return this.player_character;
	}
	public Vector<Tile> getTiles()
	{		
		return this.tiles;
	}
	
	// Builds the map ----------------------------------------------------
	public void createMap()
	{
		config.readFile();
		
		int tile_list_size = this.width * this.height;
		
		for(int i = 0; i < tile_list_size; i++)
		{
			createTile(i);
		}
		
		this.addCharacterToTile();
		this.linkTiles();
		
	}
	
	// Fills tiles accordingly -------------------------------------------
	public void createTile(int index)
	{
		if(this.config.getConfig(index) == 49)
		{
			this.tiles.add(new WallTile());
		}
		else if(this.config.getConfig(index) == 50)
		{
			this.tiles.add(new DoorTile());
		}
		else if(this.config.getConfig(index) == 51)
		{
			this.tiles.add(new WarpTile());
		}
		else
		{
			this.tiles.add(new Tile());
		}
	}
	
	// Adds a character to a tile ----------------------------------------
	public void addCharacterToTile()
	{
		this.tiles.elementAt(85).setCharacter(this.player_character = 
			new PlayerCharacter(this.tiles.elementAt(85)));
		
		this.tiles.elementAt(86).setCharacter(new GoblinCharacter(this.tiles.elementAt(86)));
		
		this.tiles.elementAt(75).setItem(new ItemSmallPotion());
		this.tiles.elementAt(65).setEvent(new FiretrapEvent());
	}

	// Links the tiles to its neighbors ----------------------------------
	public void linkTiles()
	{
		// North neighbors
		Iterator<Tile> north_iterator = this.tiles.iterator();
		for(int i = 0; i < this.tiles.size(); i++)
		{
			if(i < this.width)
			{
				north_iterator.next().setNeighbor(null, Direction.NORTH);
			}
			else
			{
				north_iterator.next().setNeighbor(this.tiles.
						elementAt(i - this.width),	Direction.NORTH);
			}
		}
		
		// West neighbor
		Iterator<Tile> west_iterator = this.tiles.iterator();
		for(int i = 0; i < this.tiles.size(); i++)
		{
			if(i % this.width == 0)
			{
				west_iterator.next().setNeighbor(null, Direction.WEST);
			}
			else
			{
				west_iterator.next().setNeighbor(this.tiles.elementAt(i - 1), 
						Direction.WEST);
			}
		}
		
		// East neighbor
		Iterator<Tile> east_iterator = this.tiles.iterator();
		for(int i = 0; i < this.tiles.size(); i++)
		{
			if(i % this.width == this.width - 1)
			{
				east_iterator.next().setNeighbor(null, Direction.EAST);
			}
			else
			{
				east_iterator.next().setNeighbor(this.tiles.elementAt(i + 1), 
						Direction.EAST);
			}
		}
		
		// South neighbors
		Iterator<Tile> south_iterator = this.tiles.iterator();
		for(int i = 0; i < this.tiles.size(); i++)
		{
			if(i > (this.width * (this.height - 1)) - 1)
			{
				south_iterator.next().setNeighbor(null, Direction.SOUTH);
			}
			else
			{
				south_iterator.next().setNeighbor
					(this.tiles.elementAt(i + this.width),	Direction.SOUTH);
			}
		}
	}
	
	// Prints or draws the map -------------------------------------------
	public void printMap()
	{
		Iterator<Tile> current_tile = this.tiles.iterator();
		
		while(current_tile.hasNext())
		{
			for(int x = 0; x < this.height; x++)
			{
				for(int y = 0; y < this.width; y++)
				{
					Tile nexttile = current_tile.next();
					Character character = nexttile.getCharacter();
					
					if(character == null && nexttile.getItem() == null && 
							nexttile.getEvent() == null) // no char, item or event
					{
						// Door test -----------------------------------------------
						if(nexttile.getTileType() == TileType.DOOR) // is door
						{
							DoorTile next_doortile = (DoorTile) nexttile;
							
							if(next_doortile.getOpened() == true) // is opened
							{
								System.out.print(next_doortile.getTestOpen() + " ");
							}
							else if(next_doortile.getOpened() == false) // is closed
							{
								System.out.print(next_doortile.getTest() + " ");
							}
						}
						else
						{
							System.out.print(nexttile.getTest() + " "); // not door
						}
						// Door test end -------------------------------------------
					}
					else if(nexttile.getCharacter() != null) // character
					{
						System.out.print(character.getTest() + " ");
					}
					else if(nexttile.getItem() != null) // item
					{
						System.out.print(nexttile.getItem().getTest() + " ");
					}
					else if(nexttile.getEvent() != null) // event
					{
						// Warning for event - REMOVE BEFORE FINAL!
						System.out.print(nexttile.getEvent().getTest() + " ");
					}
					
				}
				System.out.println();
			}
		}
	}
}
